#include "Rainr.Sockets.h"

namespace Rainr
{
    Thread::Thread()
    {
        this->mutex = nullptr;
        this->handle = nullptr;
    }
    bool Thread::Start(LPTHREAD_START_ROUTINE Function,PVOID Context)
    {
        return this->Start(Function,Context,0);
    }
    bool Thread::Start(LPTHREAD_START_ROUTINE Function,PVOID Context,DWORD Flags)
    {
        if(nullptr!= this->handle)
        {
            return false;
        }
        this->handle= CreateThread(NULL,0,Function,Context,Flags,NULL);
        if(nullptr== this->handle)
        {
            return false;
        }
        return true;
    }

    void Thread::Exit()
    {
        if(nullptr!= this->mutex)
        {
            if(CloseHandle(this->mutex))
            {
                this->mutex = nullptr;
            }
        }
        this->handle = nullptr;
        ExitThread(0);
    }

    bool Thread::Close()
    {
        return this->Close(INFINITE);
    }
    bool Thread::Close(DWORD waitMilliseconds)
    {
        if(nullptr!= this->handle)
        {
            DWORD result= WaitForSingleObject(this->handle,waitMilliseconds);
            if(
                WAIT_TIMEOUT== result
                ||
                WAIT_FAILED== result
                )
            {
                return false;
            }
            if(CloseHandle(this->handle))
            {
                this->handle = nullptr;
            }
        }
        if(nullptr!= this->mutex)
        {
            if(CloseHandle(this->mutex))
            {
                this->mutex = nullptr;
            }
        }
        return true;
    }

    void Thread::Lock()
    {
        if(nullptr== this->mutex)
        {
            this->mutex = CreateMutex(NULL,FALSE,NULL);
        }
        WaitForSingleObject(this->mutex,INFINITE);
    }
    void Thread::UnLock()
    {
        if(nullptr!= this->mutex)
        {
            ReleaseMutex(this->mutex);
        }
    }

    bool Thread::IsStarted()
    {
        return nullptr!= this->handle;
    }
}